/* $Id:race.h $ */
/*
   Copyright (C) 2007 by Jurjen Stellingwerff <jurjen@stwerff.xs4all.nl>
   Part of the Moros Project http://moros.sourceforge.net/

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License version 3.
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY.

   See the COPYING file for more details.
*/

#ifndef __RACE_H
#define __RACE_H

#include <string>
#include <map>
#include <list>
using namespace std;

#include "action_level.h"
#include "material.h"
#include "background_level.h"
#include "skill_level.h"
#include "unit.h"
#include "culture.h"

#define loopRaceSpecial(r,v) loopMapi((r)->listSpecial(),v,class action_level)
#define loopRaceWeapons(r,v) loopSingle((r)->listWeapons(),v,class material,list)
#define loopRaceBackground(r,v) loopSingle((r)->listBackground(),v,class background_level,list)
#define loopRaceSkill(r,v) loopMap((r)->listSkill(),v,class skill_level)
#define loopRaceUnit(r,v) loopMap((r)->listUnit(),v,class unit)
#define loopRaceCulture(r,v) loopMap((r)->listCulture(),v,class culture)

class race {
    string name;
    string description;
    int size;
    map<int,class action_level> special;
    int maxSpecial;
    map<string,class material> weapons;
    int age_percentage;
    class aging *aging;
    int reach;
    map<string,class background_level> background;
    map<string,class skill_level> skill;
    int armor;
    map<string,class unit> unit;
    map<string,class culture> culture;
public:
    race();

    // Field : name
    const string getName() const;
    void setName(const string v);

    // Field : description
    const string getDescription() const;
    void setDescription(const string v);

    // Field : size
    const int getSize() const;
    void setSize(const int v);

    // Field : special
    class action_level& getSpecial(const int v);
    map<int,class action_level>& listSpecial();
    void setSpecial(class action_level &v);
    void delSpecial(const int v);
    const bool isSpecial(const int v) const;

    // Field : weapons
    class material& getWeapons(const string v);
    list<class material>& listWeapons();
    void setWeapons(class material &v);
    void delWeapons(const string v);
    const bool isWeapons(const string v) const;

    // Field : age_percentage
    const int getAge_percentage() const;
    void setAge_percentage(const int v);

    // Field : aging
    class aging& getAging() const;
    void setAging(class aging &v);

    // Field : reach
    const int getReach() const;
    void setReach(const int v);

    // Field : background
    class background_level& getBackground(const string v);
    list<class background_level>& listBackground();
    void setBackground(class background_level &v);
    void delBackground(const string v);
    const bool isBackground(const string v) const;

    // Field : skill
    class skill_level& getSkill(const string v);
    map<string,class skill_level>& listSkill();
    void setSkill(class skill_level &v);
    void delSkill(const string v);
    const bool isSkill(const string v) const;

    // Field : armor
    const int getArmor() const;
    void setArmor(const int v);

    // Field : unit
    class unit& getUnit(const string v);
    map<string,class unit>& listUnit();
    void setUnit(class unit &v);
    void delUnit(const string v);
    const bool isUnit(const string v) const;

    // Field : culture
    class culture& getCulture(const string v);
    map<string,class culture>& listCulture();
    void setCulture(class culture &v);
    void delCulture(const string v);
    const bool isCulture(const string v) const;

    void save(class channel &ch);
    void load(class channel &ch);
    void xml(ofstream &f, int l=0, int r=0);
};

// Repository

#define loopRaces(v) loopMap(race_repo.listRace(),v,class race)

class raceRepository {
    map<string,race> races;
public:
    class race& getRace(const string v);
    void setRace(class race& v);
    map<string,class race>& listRace();
    void delRace(const string v);
    const bool isRace(const string v) const;
    multimap<string, sigc::signal<void, class race& > > relations;
    bool load(class channel &ch);
    void save(class channel &ch);
};

extern raceRepository race_repo;

#endif // __RACE_H
